<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>OSS 页面渲染工具</title>
    <style>
        /* 工具自身样式：仅作用于选择界面，不污染渲染页面 */
        :root {
            --primary: #6366f1;
            --primary-dark: #4f46e5;
            --primary-light: #818cf8;
            --gray-light: #f8fafc;
            --gray: #e2e8f0;
            --text-dark: #1e293b;
            --text-gray: #64748b;
            --gradient-start: #667eea;
            --gradient-end: #764ba2;
        }
        * {
            box-sizing: border-box;
        }
        body {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            background-attachment: fixed;
            min-height: 100vh;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            color: var(--text-dark);
            -webkit-tap-highlight-color: transparent;
            margin: 0;
            padding: 12px 0;
        }
        @media (min-width: 640px) {
            body {
                padding: 20px 0;
            }
        }
        .tool-container {
            max-width: 1280px;
            margin: 0 auto;
            padding: 12px;
        }
        @media (min-width: 640px) {
            .tool-container {
                padding: 20px;
            }
        }
        /* 卡片容器：2列网格布局 */
        #cardsContainer {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 12px;
            max-height: calc(100vh - 60px);
            overflow-y: auto;
            overflow-x: hidden;
            padding-right: 4px;
            margin-bottom: 16px;
            -webkit-overflow-scrolling: touch;
        }
        @media (min-width: 640px) {
            #cardsContainer {
                gap: 16px;
                max-height: calc(100vh - 100px);
                padding-right: 8px;
                margin-bottom: 28px;
            }
        }
        @media (min-width: 1024px) {
            #cardsContainer {
                gap: 20px;
            }
        }
        /* 自定义滚动条样式 */
        #cardsContainer::-webkit-scrollbar {
            width: 6px;
        }
        @media (min-width: 640px) {
            #cardsContainer::-webkit-scrollbar {
                width: 8px;
            }
        }
        #cardsContainer::-webkit-scrollbar-track {
            background: rgba(255, 255, 255, 0.1);
            border-radius: 10px;
        }
        #cardsContainer::-webkit-scrollbar-thumb {
            background: linear-gradient(135deg, rgba(99, 102, 241, 0.6) 0%, rgba(139, 92, 246, 0.6) 100%);
            border-radius: 10px;
        }
        #cardsContainer::-webkit-scrollbar-thumb:hover {
            background: linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.8) 100%);
        }
        .card {
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            touch-action: manipulation;
            position: relative;
            overflow: hidden;
            height: 120px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            border-radius: 12px;
            padding: 16px;
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            cursor: pointer;
        }
        @media (min-width: 640px) {
            .card {
                height: 140px;
                border-radius: 16px;
                padding: 24px;
            }
        }
        .card::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
            transition: left 0.5s;
        }
        .card:hover::before {
            left: 100%;
        }
        .card:active {
            transform: translateY(2px) scale(0.98);
        }
        .card-hover:hover {
            transform: translateY(-8px) scale(1.02);
            box-shadow: 0 20px 40px -12px rgba(99, 102, 241, 0.25);
        }
        @media (max-width: 639px) {
            .card-hover:active {
                transform: translateY(-2px) scale(0.98);
                box-shadow: 0 10px 20px -8px rgba(99, 102, 241, 0.2);
            }
        }
        .card-selected {
            border: 3px solid rgba(255, 255, 255, 0.6) !important;
            box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3), 0 10px 30px -5px rgba(0, 0, 0, 0.3), inset 0 0 20px rgba(255, 255, 255, 0.1) !important;
            transform: scale(1.03) !important;
        }
        /* 卡片渐变背景 */
        .card-gradient-emerald {
            background: linear-gradient(to bottom right, #10b981, #14b8a6);
        }
        .card-gradient-orange {
            background: linear-gradient(to bottom right, #f97316, #ef4444);
        }
        .card-gradient-amber {
            background: linear-gradient(to bottom right, #f59e0b, #eab308);
        }
        .card-gradient-rose {
            background: linear-gradient(to bottom right, #f43f5e, #ec4899);
        }
        .card-gradient-lime {
            background: linear-gradient(to bottom right, #84cc16, #22c55e);
        }
        .card-gradient-fuchsia {
            background: linear-gradient(to bottom right, #d946ef, #a855f7);
        }
        .card-gradient-sky {
            background: linear-gradient(to bottom right, #0ea5e9, #3b82f6);
        }
        .card-gradient-red {
            background: linear-gradient(to bottom right, #ef4444, #f97316);
        }
        .card-gradient-violet {
            background: linear-gradient(to bottom right, #8b5cf6, #6366f1);
        }
        .card-gradient-indigo {
            background: linear-gradient(to bottom right, #6366f1, #8b5cf6);
        }
        /* 卡片内容 */
        .card-content {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            text-align: center;
            width: 100%;
        }
        .card-icon-wrapper {
            width: 48px;
            height: 48px;
            border-radius: 12px;
            background: rgba(255, 255, 255, 0.2);
            backdrop-filter: blur(4px);
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
        @media (min-width: 640px) {
            .card-icon-wrapper {
                width: 56px;
                height: 56px;
                border-radius: 16px;
                margin-bottom: 12px;
            }
        }
        .card-icon {
            width: 20px;
            height: 20px;
            fill: white;
        }
        @media (min-width: 640px) {
            .card-icon {
                width: 24px;
                height: 24px;
            }
        }
        .card-title {
            font-weight: 700;
            font-size: 14px;
            color: white;
            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
            width: 100%;
            padding: 0 4px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            margin-top: 10px;
        }
        @media (min-width: 640px) {
            .card-title {
                font-size: 16px;
            }
        }
        /* 自定义卡片特殊样式 */
        .custom-card {
            border: 2px dashed rgba(255, 255, 255, 0.3);
        }
        .custom-card:hover {
            border-color: rgba(255, 255, 255, 0.5);
        }
        /* 自定义输入区域 */
        .custom-input-area {
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(12px);
            border-radius: 12px;
            box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
            padding: 16px;
            margin-bottom: 16px;
        }
        @media (min-width: 640px) {
            .custom-input-area {
                border-radius: 16px;
                padding: 24px;
                margin-bottom: 24px;
            }
        }
        .custom-input-header {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 16px;
        }
        @media (min-width: 640px) {
            .custom-input-header {
                gap: 12px;
                margin-bottom: 20px;
            }
        }
        .custom-input-icon-wrapper {
            width: 32px;
            height: 32px;
            border-radius: 8px;
            background: linear-gradient(to bottom right, #6366f1, #8b5cf6);
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            flex-shrink: 0;
        }
        @media (min-width: 640px) {
            .custom-input-icon-wrapper {
                width: 40px;
                height: 40px;
                border-radius: 12px;
            }
        }
        .custom-input-icon {
            width: 14px;
            height: 14px;
            fill: white;
        }
        @media (min-width: 640px) {
            .custom-input-icon {
                width: 16px;
                height: 16px;
            }
        }
        .custom-input-title {
            font-weight: 700;
            font-size: 16px;
            background: linear-gradient(to right, #4f46e5, #7c3aed);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }
        @media (min-width: 640px) {
            .custom-input-title {
                font-size: 18px;
            }
        }
        .custom-input-form {
            display: flex;
            flex-direction: column;
            gap: 12px;
        }
        @media (min-width: 640px) {
            .custom-input-form {
                gap: 16px;
            }
        }
        .custom-input {
            width: 100%;
            padding: 12px 16px;
            border: 2px solid #e2e8f0;
            border-radius: 8px;
            font-size: 14px;
            transition: all 0.3s ease;
            background: #f8fafc;
        }
        @media (min-width: 640px) {
            .custom-input {
                padding: 16px 20px;
                border-radius: 12px;
            }
        }
        .custom-input:focus {
            outline: none;
            border-color: var(--primary);
            box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
            background: white;
        }
        .btn-primary {
            width: 100%;
            background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
            color: white;
            font-weight: 600;
            padding: 12px 20px;
            border-radius: 8px;
            border: none;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
            font-size: 14px;
            box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4);
            transition: all 0.3s ease;
        }
        @media (min-width: 640px) {
            .btn-primary {
                padding: 16px 24px;
                border-radius: 12px;
            }
        }
        .btn-primary:hover {
            background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%);
            box-shadow: 0 6px 20px rgba(99, 102, 241, 0.5);
            transform: translateY(-2px);
        }
        .btn-primary:active {
            transform: translateY(0);
            box-shadow: 0 2px 10px rgba(99, 102, 241, 0.3);
        }
        .btn-icon {
            width: 16px;
            height: 16px;
            fill: white;
        }
        /* 错误提示 */
        .error-msg {
            position: fixed;
            top: 64px;
            left: 50%;
            transform: translateX(-50%);
            width: calc(100% - 24px);
            max-width: 448px;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(12px);
            border: 2px solid #fecaca;
            border-radius: 12px;
            padding: 12px;
            margin-bottom: 24px;
            color: #dc2626;
            z-index: 40;
            box-shadow: 0 10px 40px rgba(239, 68, 68, 0.2);
        }
        @media (min-width: 640px) {
            .error-msg {
                top: 80px;
                width: calc(100% - 32px);
                border-radius: 16px;
                padding: 16px;
            }
        }
        .error-content {
            display: flex;
            align-items: center;
            gap: 8px;
        }
        @media (min-width: 640px) {
            .error-content {
                gap: 12px;
            }
        }
        .error-icon-wrapper {
            width: 32px;
            height: 32px;
            border-radius: 50%;
            background: #fee2e2;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }
        @media (min-width: 640px) {
            .error-icon-wrapper {
                width: 40px;
                height: 40px;
            }
        }
        .error-icon {
            width: 16px;
            height: 16px;
            fill: #dc2626;
        }
        @media (min-width: 640px) {
            .error-icon {
                width: 20px;
                height: 20px;
            }
        }
        .error-text {
            font-size: 12px;
            font-weight: 500;
            flex: 1;
        }
        @media (min-width: 640px) {
            .error-text {
                font-size: 14px;
            }
        }
        /* 加载状态 */
        .loading {
            position: fixed;
            inset: 0;
            background: linear-gradient(to bottom right, rgba(99, 102, 241, 0.9), rgba(139, 92, 246, 0.9));
            backdrop-filter: blur(4px);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 40;
        }
        .loading-content {
            background: rgba(255, 255, 255, 0.2);
            backdrop-filter: blur(12px);
            border-radius: 16px;
            padding: 24px;
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
            margin: 0 16px;
        }
        @media (min-width: 640px) {
            .loading-content {
                border-radius: 24px;
                padding: 32px;
            }
        }
        .loading-spinner-wrapper {
            position: relative;
            width: 48px;
            height: 48px;
        }
        @media (min-width: 640px) {
            .loading-spinner-wrapper {
                width: 64px;
                height: 64px;
            }
        }
        .loading-spinner {
            width: 48px;
            height: 48px;
            animation: spin 1s linear infinite;
        }
        @media (min-width: 640px) {
            .loading-spinner {
                width: 64px;
                height: 64px;
            }
        }
        .loading-text {
            margin-top: 16px;
            color: white;
            font-weight: 600;
            font-size: 14px;
        }
        @media (min-width: 640px) {
            .loading-text {
                margin-top: 24px;
                font-size: 16px;
            }
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }
        .fade-in {
            animation: fadeIn 0.5s ease-out;
        }
        html {
            scroll-behavior: smooth;
            -webkit-overflow-scrolling: touch;
        }
        input:focus-visible {
            outline: none;
        }
        .hidden {
            display: none !important;
        }
        /* 关键：渲染容器样式隔离，不继承工具样式 */
        #renderWrapper {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 9999;
            display: none;
            overflow: auto;
        }
        /* 关闭按钮：悬浮在左上角，不干扰页面 */
        .close-btn {
            position: fixed;
            top: 12px;
            left: 12px;
            width: 32px;
            height: 32px;
            border-radius: 50%;
            background: linear-gradient(135deg, rgba(99, 102, 241, 0.9) 0%, rgba(139, 92, 246, 0.9) 100%);
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10000;
            cursor: pointer;
            box-shadow: 0 4px 20px rgba(99, 102, 241, 0.4);
            transition: all 0.3s ease;
            backdrop-filter: blur(10px);
        }
        @media (min-width: 640px) {
            .close-btn {
                top: 20px;
                left: 20px;
                width: 36px;
                height: 36px;
            }
        }
        .close-btn:hover {
            background: linear-gradient(135deg, rgba(99, 102, 241, 1) 0%, rgba(139, 92, 246, 1) 100%);
            transform: scale(1.1);
            box-shadow: 0 6px 25px rgba(99, 102, 241, 0.6);
        }
        .close-btn:active {
            transform: scale(0.95);
        }
        .close-icon {
            width: 14px;
            height: 14px;
            fill: white;
        }
        /* 渲染目标：iframe 完全隔离，样式不继承工具 */
        #renderTarget {
            width: 100%;
            height: 100%;
            border: none;
            margin: 0;
            padding: 0;
            display: block;
        }
    </style>
</head>
<body>
    <!-- 工具选择界面 -->
    <div class="tool-container">
        <!-- 卡片容器：固定2列布局 -->
        <div id="cardsContainer">
            <!-- 动态生成的卡片将插入这里 -->
            
            <!-- 自定义卡片 -->
            <div class="card card-hover card-gradient-indigo custom-card hidden" id="customCard">
                <div class="card-content">
                    <div class="card-icon-wrapper">
                        <svg class="card-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <line x1="12" y1="5" x2="12" y2="19"></line>
                            <line x1="5" y1="12" x2="19" y2="12"></line>
                        </svg>
                    </div>
                    <h3 class="card-title">自定义地址</h3>
                </div>
            </div>
        </div>

        <!-- 自定义输入区域 -->
        <div class="custom-input-area hidden fade-in" id="customInputArea">
            <div class="custom-input-header">
                <div class="custom-input-icon-wrapper">
                    <svg class="custom-input-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path>
                        <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
                    </svg>
                </div>
                <h3 class="custom-input-title">自定义 OSS 地址</h3>
            </div>
            <div class="custom-input-form">
                <input 
                    type="url" 
                    id="customOssUrl" 
                    class="custom-input"
                    placeholder="示例：https://xxx.oss-cn-xxx.aliyuncs.com/custom.html"
                >
                <button onclick="renderOssHtml()" class="btn-primary">
                    <svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"></path>
                    </svg>
                    <span>立即渲染</span>
                </button>
            </div>
        </div>

        <!-- 错误提示 -->
        <div class="error-msg hidden fade-in" id="errorMsg">
            <div class="error-content">
                <div class="error-icon-wrapper">
                    <svg class="error-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <circle cx="12" cy="12" r="10"></circle>
                        <line x1="12" y1="8" x2="12" y2="12"></line>
                        <line x1="12" y1="16" x2="12.01" y2="16"></line>
                    </svg>
                </div>
                <span class="error-text" id="errorText"></span>
            </div>
        </div>

        <!-- 加载状态 -->
        <div class="loading hidden" id="loading">
            <div class="loading-content">
                <div class="loading-spinner-wrapper">
                    <svg class="loading-spinner" fill="none" stroke="currentColor" viewBox="0 0 40 40">
                        <circle cx="20" cy="20" r="18" fill="none" stroke-width="3" stroke-dasharray="113.1" stroke-dashoffset="0" stroke-linecap="round" opacity="0.3"></circle>
                        <circle cx="20" cy="20" r="18" fill="none" stroke-width="3" stroke-dasharray="113.1" stroke-dashoffset="56.55" stroke-linecap="round"></circle>
                    </svg>
                </div>
                <p class="loading-text">加载中...</p>
            </div>
        </div>
    </div>

    <!-- 渲染页面容器（关键：独立于工具界面，全屏显示） -->
    <div id="renderWrapper">
        <!-- 关闭按钮 -->
        <div class="close-btn" onclick="closeRender()">
            <svg class="close-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <line x1="18" y1="6" x2="6" y2="18"></line>
                <line x1="6" y1="6" x2="18" y2="18"></line>
            </svg>
        </div>
        <!-- 渲染目标：iframe 完全隔离，样式不继承工具 -->
        <iframe id="renderTarget" sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-modals"></iframe>
    </div>

    <script>
        let selectedUrl = '';
        const errorMsgEl = document.getElementById('errorMsg');
        const errorTextEl = document.getElementById('errorText');
        const loadingEl = document.getElementById('loading');
        const renderWrapper = document.getElementById('renderWrapper');
        const renderTarget = document.getElementById('renderTarget');
        const toolContainer = document.querySelector('.tool-container');
        const cardsContainer = document.getElementById('cardsContainer');
        const customCard = document.getElementById('customCard');

        // 图标 SVG 路径配置
        const cardIcons = [
            '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline>',
            '<rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect>',
            '<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle>',
            '<polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline><polyline points="17 6 23 6 23 12"></polyline>',
            '<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line>',
            '<line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line>'
        ];
        
        // 颜色配置
        const cardColors = [
            { bg: 'card-gradient-emerald' },
            { bg: 'card-gradient-orange' },
            { bg: 'card-gradient-amber' },
            { bg: 'card-gradient-rose' },
            { bg: 'card-gradient-lime' },
            { bg: 'card-gradient-fuchsia' },
            { bg: 'card-gradient-sky' },
            { bg: 'card-gradient-red' },
            { bg: 'card-gradient-violet' }
        ];

        /**
         * 从本地缓存读取列表数据
         */
        function getCachedCardList() {
            try {
                const cached = localStorage.getItem('ossCardList');
                if (cached) {
                    const data = JSON.parse(cached);
                    // 检查缓存是否过期（24小时）
                    const now = Date.now();
                    if (data.timestamp && (now - data.timestamp) < 24 * 60 * 60 * 1000) {
                        return data.list;
                    }
                }
            } catch (error) {
                console.error('读取缓存失败:', error);
            }
            return null;
        }

        /**
         * 保存列表数据到本地缓存
         */
        function saveCardListToCache(list) {
            try {
                const data = {
                    list: list,
                    timestamp: Date.now()
                };
                localStorage.setItem('ossCardList', JSON.stringify(data));
            } catch (error) {
                console.error('保存缓存失败:', error);
            }
        }

        /**
         * 从接口获取列表数据
         */
        async function fetchCardList() {
            const apiUrl = 'https://gstor-default-workspace-cn-shanghai-c218770b.oss-cn-shanghai.aliyuncs.com/AICont/api/table.json';
            
            try {
                const response = await fetch(apiUrl, {
                    method: 'GET',
                    headers: { 'Accept': 'application/json' }
                });

                if (!response.ok) {
                    throw new Error(`请求失败：${response.status}`);
                }

                const result = await response.json();
                
                if (result.code === 200 && result.data && result.data.list) {
                    // 保存到缓存
                    saveCardListToCache(result.data.list);
                    renderCards(result.data.list);
                } else {
                    showError('获取列表数据失败');
                    // 即使接口失败，也要显示自定义卡片
                    customCard.classList.remove('hidden');
                }
            } catch (error) {
                console.error('获取列表数据错误:', error);
                showError('获取列表数据失败，请检查网络连接');
                // 即使接口失败，也要显示自定义卡片
                customCard.classList.remove('hidden');
            }
        }

        /**
         * 动态渲染卡片
         */
        function renderCards(list) {
            // 清空现有卡片（保留自定义卡片）
            const existingCards = cardsContainer.querySelectorAll('[data-url]');
            existingCards.forEach(card => card.remove());

            // 生成新卡片
            list.forEach((item, index) => {
                const card = createCard(item, index);
                // 插入到自定义卡片之前
                cardsContainer.insertBefore(card, customCard);
            });

            // 显示自定义卡片（接口数据加载完成后）
            customCard.classList.remove('hidden');

            // 不需要重新绑定事件，因为使用了事件委托
        }

        /**
         * 创建单个卡片元素
         */
        function createCard(item, index) {
            const iconIndex = index % cardIcons.length;
            const colorIndex = index % cardColors.length;
            const color = cardColors[colorIndex];
            const iconPath = cardIcons[iconIndex];

            const card = document.createElement('div');
            card.className = `card card-hover ${color.bg}`;
            card.setAttribute('data-url', item.path);
            card.innerHTML = `
                <div class="card-content">
                    <div class="card-icon-wrapper">
                        <svg class="card-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            ${iconPath}
                        </svg>
                    </div>
                    <h3 class="card-title">${item.name || '未命名页面'}</h3>
                </div>
            `;
            return card;
        }

        // 页面加载初始化
        window.onload = async () => {
            // 使用事件委托绑定卡片点击事件（只绑定一次，自动处理动态添加的卡片）
            cardsContainer.addEventListener('click', function(e) {
                // 查找被点击的卡片（向上查找最近的 data-url 元素）
                const card = e.target.closest('[data-url]');
                if (card) {
                    // 阻止事件冒泡
                    e.stopPropagation();
                    
                    // 移除所有卡片的选中状态
                    const allCards = cardsContainer.querySelectorAll('[data-url]');
                    allCards.forEach(c => c.classList.remove('card-selected'));
                    customCard.classList.remove('card-selected');
                    
                    // 选中当前卡片
                    card.classList.add('card-selected');
                    selectedUrl = card.dataset.url;
                    document.getElementById('customInputArea').classList.add('hidden');
                    errorMsgEl.classList.add('hidden');
                    
                    // 自动触发渲染
                    renderOssHtml();
                }
            });

            // 先尝试从缓存读取数据
            const cachedList = getCachedCardList();
            if (cachedList && cachedList.length > 0) {
                renderCards(cachedList);
                // 如果使用缓存数据，自定义卡片已经在 renderCards 中显示了
            } else {
                // 如果没有缓存，等接口完成后再显示自定义卡片
            }

            // 然后请求接口更新数据
            await fetchCardList();

            // 自定义卡片点击
            customCard.addEventListener('click', () => {
                const presetCards = document.querySelectorAll('[data-url]');
                presetCards.forEach(c => c.classList.remove('card-selected'));
                customCard.classList.add('card-selected');
                document.getElementById('customInputArea').classList.remove('hidden');
                selectedUrl = '';
                errorMsgEl.classList.add('hidden');
                setTimeout(() => {
                    document.getElementById('customOssUrl').focus();
                }, 300);
            });
        };

        /**
         * 核心渲染功能：完全隔离样式
         */
        async function renderOssHtml() {
            const customUrl = document.getElementById('customOssUrl')?.value.trim() || '';
            const finalUrl = selectedUrl || customUrl;

            // 验证
            if (!finalUrl) {
                showError('请选择预设卡片或输入自定义地址');
                return;
            }
            
            // 验证 URL 格式（放宽验证，允许 URL 编码字符）
            try {
                new URL(finalUrl);
            } catch (e) {
                showError('请输入有效的 URL 地址');
                return;
            }
            
            if (!finalUrl.toLowerCase().includes('.html')) {
                showError('请输入有效的 HTML 链接（包含 .html）');
                return;
            }

            // 显示加载
            errorMsgEl.classList.add('hidden');
            loadingEl.classList.remove('hidden');

            try {
                // 30秒超时
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 30000);

                const response = await fetch(finalUrl, {
                    method: 'GET',
                    headers: { 'Accept': 'text/html' },
                    signal: controller.signal,
                    mode: 'cors'
                });

                clearTimeout(timeoutId);

                if (!response.ok) {
                    throw new Error(`请求失败：${response.status} ${response.statusText}`);
                }

                // 读取HTML内容
                const htmlContent = await response.text();
                
                if (!htmlContent || htmlContent.trim().length === 0) {
                    throw new Error('获取的 HTML 内容为空');
                }

                // 隐藏工具界面，显示渲染界面
                toolContainer.style.display = 'none';
                renderWrapper.style.display = 'block';

                // 确保 iframe 已初始化（首次使用时设置 about:blank）
                if (!renderTarget.src) {
                    renderTarget.src = 'about:blank';
                }

                // 等待 iframe 的 document 可用
                await new Promise((resolve) => {
                    const getDoc = () => {
                        return renderTarget.contentDocument || renderTarget.contentWindow?.document;
                    };
                    
                    if (getDoc()) {
                        resolve();
                        return;
                    }
                    
                    const checkReady = () => {
                        if (getDoc()) {
                            resolve();
                        } else {
                            setTimeout(checkReady, 10);
                        }
                    };
                    
                    renderTarget.onload = resolve;
                    checkReady();
                });

                // 将 HTML 内容写入 iframe 的 document
                const iframeDoc = renderTarget.contentDocument || renderTarget.contentWindow.document;
                iframeDoc.open();
                iframeDoc.write(htmlContent);
                iframeDoc.close();

                // 同步原页面标题
                const titleMatch = htmlContent.match(/<title>([\s\S]*?)<\/title>/i);
                if (titleMatch && titleMatch[1]) {
                    document.title = titleMatch[1].trim();
                }

            } catch (error) {
                console.error('渲染错误:', error);
                if (error.name === 'AbortError') {
                    showError('请求超时，请检查网络或链接');
                } else if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
                    showError('网络请求失败，可能是 CORS 问题或链接无法访问');
                } else {
                    showError(`渲染失败：${error.message}`);
                }
            } finally {
                loadingEl.classList.add('hidden');
            }
        }

        /**
         * 关闭渲染页面，返回工具界面（直接刷新页面）
         */
        function closeRender() {
            // 直接刷新页面，确保所有状态重置
            location.reload();
        }


        /**
         * 显示错误提示
         */
        function showError(msg) {
            errorTextEl.textContent = msg;
            errorMsgEl.classList.remove('hidden');
            setTimeout(() => {
                errorMsgEl.classList.add('hidden');
            }, 3000);
        }

        // Escape 键关闭渲染页面
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape' && renderWrapper.style.display === 'block') {
                closeRender();
            }
        });
    </script>
</body>
</html>
